home *** CD-ROM | disk | FTP | other *** search
- /*--------------------------------------------------------------------------*\
- | RLE.C - RLE Delta frame code |
- | |
- \*--------------------------------------------------------------------------*/
-
-
- /*
- (C) Copyright Microsoft Corp. 1991, 1992. All rights reserved.
-
- You have a royalty-free right to use, modify, reproduce and
- distribute the Sample Files (and/or any modified version) in
- any way you find useful, provided that you agree that
- Microsoft has no warranty obligations or liability for any
- Sample Application Files which are modified.
-
- If you did not get this from Microsoft Sources, then it may not be the
- most current version. This sample code in particular will be updated
- and include more documentation.
-
- Sources are:
- The MM Sys BBS: The phone number is 206 936-4082.
- CompuServe: WINSDK forum, MDK section.
- */
-
-
- #include <windows.h>
- #include "gmem.h"
- #include "dib.h"
- #include "rle.h"
-
- extern WORD PASCAL __WinFlags;
- #define WinFlags (WORD)(&__WinFlags)
-
- #define RLE_ESCAPE 0
- #define RLE_EOL 0
- #define RLE_EOF 1
- #define RLE_JMP 2
- #define RLE_RUN 3
-
- typedef BYTE huge * HPRLE;
- typedef BYTE far * LPRLE;
-
- /*----------------------------------------------------------------------------*\
- * MEM.ASM
- \*----------------------------------------------------------------------------*/
- extern LPVOID FAR PASCAL MemCopy(LPVOID dest, LPVOID source, LONG count);
- extern LPVOID FAR PASCAL MemFill(LPVOID dest, LONG count, BYTE b);
- extern long FAR PASCAL muldiv32(long,long,long);
-
- void FAR PASCAL DecodeRle386(LPBITMAPINFOHEADER lpbi, LPBYTE pb, LPBYTE prle);
- void NEAR PASCAL DecodeRle286(LPBITMAPINFOHEADER lpbi, HPRLE pb, HPRLE prle);
-
- //
- // RleDeltaFrame
- //
- // Calculate the RLE bits to go from one dib to another
- //
- // hdibPrev - Previous DIB
- // hdib - DIB to RLE
- //
- // returns
- //
- // handle to a RLE DIB
- //
- HANDLE FAR PASCAL RleDeltaFrame(HANDLE hrle, HANDLE hdibPrev, HANDLE hdib, int iStart, int iLen, int minJump)
- {
- LPBITMAPINFOHEADER lpbi;
-
- BOOL fAlloc;
- LPBYTE pbPrev;
- LPBYTE pbDib;
- LPBYTE pbRle;
- int biHeight;
- WORD cbJump=0;
- int dy;
-
- if (!hdib)
- return NULL;
-
- if (minJump == 0)
- minJump = 4;
-
- //
- // Get info on the source and dest dibs
- //
- lpbi = GLock(hdib);
- biHeight = (int)lpbi->biHeight;
-
- if (iLen <= 0)
- iLen = biHeight;
-
- iLen = min(biHeight-iStart, iLen);
-
- //
- // Hey! we only work with 8bpp DIBs if we get otherwise barf.
- //
- if (lpbi->biBitCount != 8 || lpbi->biCompression != BI_RGB)
- return NULL;
-
- //
- // create an RLE buffer to place the RLE bits in
- //
- if (fAlloc = !hrle)
- {
- hrle = CreateDib(8, (int)lpbi->biWidth, (int)lpbi->biHeight*2);
-
- if (!hrle)
- return NULL;
-
- //
- // copy over the color table from the DIB to the empty RLE
- //
- MemCopy(GLock(hrle),GLock(hdib),(int)lpbi->biSize+(int)lpbi->biClrUsed*sizeof(RGBQUAD));
- }
-
- //
- // lock all the buffers, and start the delta framin'
- //
- lpbi = GLock(hrle);
- pbRle = DibPtr(hrle);
- pbDib = DibLock(hdib,0,iStart);
-
- if (hdibPrev)
- pbPrev = DibLock(hdibPrev,0,iStart);
- else
- pbPrev = NULL;
-
- while(iStart > 0)
- {
- dy = min(iStart,255);
- *pbRle++ = RLE_ESCAPE;
- *pbRle++ = RLE_JMP;
- *pbRle++ = 0;
- *pbRle++ = (BYTE)dy;
- iStart -= dy;
- cbJump += 4;
- }
-
- lpbi->biHeight = iLen;
-
- DeltaFrame386(lpbi, pbPrev, pbDib, pbRle, minJump);
-
- lpbi->biHeight = biHeight;
- lpbi->biSizeImage += cbJump; // adjust size to include JUMP!
-
- //
- // hey we are done! Unlock the buffers and get out
- //
- if (fAlloc)
- hrle = GReAlloc(hrle,lpbi->biSize+lpbi->biClrUsed*sizeof(RGBQUAD)+lpbi->biSizeImage);
-
- return hrle;
- }
-
- //
- // PlayRleDib
- //
- // Play back a RLE buffer into a DIB
- //
- // hdib - dest DIB
- // x,y - position in dest DIB where to place RLE
- // hrle - src RLE
- //
- // returns
- //
- // none
- //
- void PlayRleDib(HANDLE hdib, int x, int y, HANDLE hrle)
- {
- LPBITMAPINFOHEADER lpbi;
-
- lpbi = GLock(hdib);
-
- if (WinFlags & WF_CPU286)
- DecodeRle286(lpbi, DibXY(lpbi,x,y), DibPtr(hrle));
- else
- DecodeRle386(lpbi, DibXY(lpbi,x,y), DibPtr(hrle));
- }
-
- //
- // DecodeRle286
- //
- // Play back a RLE buffer into a DIB buffer
- //
- // returns
- //
- // none
- //
- void NEAR PASCAL DecodeRle286(LPBITMAPINFOHEADER lpbi, HPRLE pb, HPRLE prle)
- {
- BYTE cnt;
- BYTE b;
- WORD x;
- WORD dx,dy;
- WORD wWidthBytes;
-
- wWidthBytes = (WORD)lpbi->biWidth+3 & ~3;
-
- x = 0;
-
- for(;;)
- {
- cnt = *prle++;
- b = *prle++;
-
- if (cnt == RLE_ESCAPE)
- {
- switch (b)
- {
- case RLE_EOF:
- return;
-
- case RLE_EOL:
- pb += wWidthBytes - x;
- x = 0;
- break;
-
- case RLE_JMP:
- dx = (WORD)*prle++;
- dy = (WORD)*prle++;
-
- pb += (DWORD)wWidthBytes * dy + dx;
- x += dx;
-
- break;
-
- default:
- cnt = b;
- x += cnt;
- while (cnt-- > 0)
- *pb++ = *prle++;
-
- if (b & 1)
- prle++;
-
- break;
- }
- }
- else
- {
- x += cnt;
-
- while (cnt-- > 0)
- *pb++ = b;
- }
- }
- }
-